package com.bond.jumper.client.screengather;

import com.bond.jumper.client.ScreenInfo;
import com.bond.jumper.client.util.PropertiesUtils;
import com.bond.jumper.common.ChannelHolder;
import com.bond.jumper.common.po.MessageToServer;
import com.bond.jumper.common.util.ImageUtils;
import com.bond.jumper.common.util.SequenceUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 客户端采集与发送
 * 该类设计用于一个生产线程，一个消费线程的工作场景。
 */
public class ClientWork {

    /**
     * 链表最大元素个数，该值用于限制采集，防止积压
     */
    private final int MAX_COUNT = 30;

    /**
     * 采集的数据链表
     */
    private LinkedList<MessageToServer> messageToServers = new LinkedList<>();

    /**
     * 公平锁
     */
    private Lock lock = new ReentrantLock(true);
    //采集线程等待队列
    private Condition gather = lock.newCondition();
    //发送线程等待队列
    private Condition sender = lock.newCondition();

    private ClientWork() {

    }

    private static ClientWork clientWork;
    private static ScreenGather screenGather;
    private static ScreenSender screenSender;

    /**
     * 令ClientWork工作
     */
    public static void startWork() {
        if (clientWork == null) {
            clientWork = new ClientWork();
            screenGather = new ScreenGather(clientWork);
            screenSender = new ScreenSender(clientWork);

            screenGather.start();
            screenSender.start();
            System.out.println("ClientWork 开始工作");
        }
    }

    /**
     * 令ClientWork停止工作
     */
    public static void stopWork() {
        if (screenGather != null)
            screenGather.interrupt();
        if (screenSender != null)
            screenSender.interrupt();
    }

    /**
     * 数据采集：生产
     *
     * @return
     */
    public void gatherMessage() {
        try {
            //System.out.println("数据采集...");
            lock.lock();

            while (messageToServers.size() == MAX_COUNT) {
                gather.await();
            }

            //采集鼠标指针位置
            PointerInfo pointerInfo = ScreenInfo.instance.getMousePointer();
            //采集屏幕图像
            BufferedImage bufferedImage = ScreenInfo.instance.getScreen(null);
            //构造消息对象
            MessageToServer messageToServer = new MessageToServer();
            messageToServer.setLicense(PropertiesUtils.getPropString("license"));
            messageToServer.setSequence(SequenceUtils.sequence());
            messageToServer.setImage(ImageUtils.bufferedImageToByteArray(bufferedImage, ImageUtils.FORMAT_JPEG));
            messageToServer.setWidth(bufferedImage.getWidth());
            messageToServer.setHeight(bufferedImage.getHeight());
            messageToServer.setPointX(pointerInfo.getLocation().getX());
            messageToServer.setPointY(pointerInfo.getLocation().getY());
            messageToServers.add(messageToServer);

            sender.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 数据发送:消费
     */
    public void sendToServer() {
        try {
            //System.out.println("数据发送");
            lock.lock();
            while (messageToServers.size() == 0) {
                sender.await();
            }
            ChannelHolder.sendMessage(messageToServers.removeFirst());
            gather.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
